/**
 * 双向链表结构
 *
 * @param type:节点类型
 * @param parent:父节点
 * @param firstChild：开始孩子节点
 * @param lastChild：结束孩子节点
 * @param pre：前一个节点
 * @param next：后一个节点
 * @param isContainer：是否包含子元素
 */
export class MNode {
    public type:string = '';
    public parent:MNode | null = null;
    public firstChild:MNode | null = null;
    public lastChild:MNode | null = null;
    public prev:MNode|null = null;
    public next:MNode|null = null;
    public isContainer:Boolean = true;

    /**
     * 从树当中删除该节点
     * 删除兄弟节点以及父节点链接
     */
    unlink() :void{
        /** 如果前节点存在 */
        if(this.prev){
            /* 将上一个节点next指向为当前节点next指向 */
            this.prev.next = this.next
        }else{
            /** 说明当前节点为父节点首个子节点 */
            this.parent? this.parent.firstChild = this.next : null
        }
        if(this.next){
            /* 将下一个节点pre指向为当前节点pre指向 */
            this.next.prev = this.prev
        }else{
            /** 说明当前节点为父节点末尾子节点 */
            this.parent? this.parent.lastChild = this.prev : null;
        }
       
        /* 删除兄弟节点以及父节点链接 */
        this.parent = null
        this.next = null
        this.prev = null
    }
    /**
     * 从该节点的子节点末尾处添加子节点
     * 1.先删除当前依赖 unlink
     * 2.添加父、兄弟间依赖
     * @param mnode 
     */
    appendChild(mnode:MNode) {
       mnode.unlink()
       /** 传入的节点指定父节点 */
       mnode.parent = this
      
       if(this.lastChild){
            /** 当前结束子节点下一个节点为设置节点 */
            this.lastChild.next = mnode
            /** 当前节点的上任节点为结束子节点 */
            mnode.prev = this.lastChild
            /** 当前结束子节点为设置节点 */
            this.lastChild = mnode

       }else{   
            /** 若当前无结束子节点 */
            this.firstChild = this.lastChild = mnode
       }
    }
    /**
     * 从该节点末尾处添加兄弟节点
     * 1.先删除当前依赖 unlink
     * 2.添加父、兄弟间依赖
     * @param mnode 
     */
    insertAfter(mnode:MNode) {
       mnode.unlink()
       /** 设置节点next为当前节点的next */
       mnode.next = this.next
       /** 设置节点pre为当前节点 */
       mnode.prev = this
       if(mnode.next){
           /** 当前节点的上一任节点为设置节点 */
           mnode.next.prev = mnode
       }
       /** 下一个节点为当前节点 */
       this.next = mnode
       /** 下一个节点父节点为当前节点父节点 */
       mnode.parent = this.parent
      
       /** 若当前没有下一个节点，且存在父亲节点 */
       if(!mnode.next && mnode.parent){
           /** 当前父亲节点最后子节点为设置节点 */
           mnode.parent.lastChild = mnode
       }
    }
}
export default MNode